#pragma once

#include <atomic>
#include <chrono>
#include <condition_variable>
#include <deque>
#include <mutex>
#include <optional>
#include <string>
#include <thread>
#include <vector>

#include "mini_redis/config.h"

namespace mini_redis {

class KeyValueStore;

#if 0
    负责实现 AOF（Append Only File，仅追加文件）持久化机制。
其核心目标是：将 mini_redis 的所有写操作（如 SET、DEL、EXPIRE 等）
以可解析的格式记录到磁盘文件中，确保服务重启后能通过回放这些操作恢复数据，
同时优化 AOF 文件体积和写入性能。

#endif

class AofLogger
{
public:
    AofLogger() = default;
    ~AofLogger()
    {
        shutdown();
    }
    void shutdown();

    // 初始化AOF
    bool init(const AofOptions& opts, std::string& err);
    // 获取文件路径
    std::string path() const;
    // 从 AOF 文件中读取并解析数据，恢复到 kv存储
    bool load(KeyValueStore& store, std::string& err);

    bool appendCommand(const std::vector<std::string>& parts);

    bool appendRaw(const std::string& raw_resp);

    void writerLoop();
    bool bgRewrite(KeyValueStore& store, std::string& err);
    void rewriterLoop(KeyValueStore* store);

    inline bool isEnabled() const
    {
        return opts_.enabled;
    }

    inline AofMode mode() const
    {
        return opts_.mode;
    }

private:
    // 1、配置相关
    AofOptions opts_;
    int        fd_ = -1;

    // 2、线程控制
    std::atomic<bool> running_{false};
    std::atomic<bool> stop_{false};
    std::thread       writer_thread_;
    std::thread       rewriter_thread_;

    // 3、同步与线程安全
    std::mutex mutex_;              // 用于保护多线程共享的数据
    std::condition_variable cv_;    // 用于唤醒 writer_thread_ 处理新命令

    //另一个条件变量，用于等待命令写入 同步完成的通知。
    std::condition_variable cv_commit_;

    // 暂停
    bool writer_is_paused_ = false;
    std::mutex pause_mtx_;    //保护 “暂停状态” 的互斥锁
    std::atomic<bool> pause_writer_{false};    // 控制 写入线程是否暂停
#if 0
    1. 写入线程检测到 pause_writer_=true 时，会通知 cv_pause_ 并等待；
    2. 重写线程等待 cv_pause_ 确认写入线程已暂停后，再处理增量命令；
    3. 重写完成后，通过 cv_pause_.notify_all() 唤醒写入线程。
#endif
    std::condition_variable cv_pause_;

    // 4、命令缓存与追踪
    struct AofItem
    {
        std::string data;
        int64_t     seq;
    };
    std::deque<AofItem>  queue_;         //待写入磁盘的命令队列
    std::atomic<int64_t> seq_gen_{0};    // 序列号生成器
    // 队列中所有未写入磁盘的命令总字节数
    size_t pending_bytes_ = 0;
    // 最后一个已成功同步到磁盘的命令序列号
    // 用于判断哪些命令已安全写入
    int64_t last_synced_seq_ = 0;

    // 记录上次 同步磁盘的时间点
    std::chrono::steady_clock::time_point last_sync_tp_{
        std::chrono::steady_clock::now()};

    int timer_fd_ = -1;

    // 5、AOF 重写相关
    std::atomic<bool> rewriting_{false};    // 标记是否正在进行 AOF 重写
    // 保护 incr_cmds_ 的互斥锁
    std::mutex incr_mtx_;
    // 重写期间的增量命令列表
    std::vector<std::string> incr_cmds_;
};

// 将命令转换为 RESP 协议格式
std::string toRespArray(const std::vector<std::string>& parts);

}    // namespace mini_redis
